package com.jackrain.nea.shiro.stateful;

import com.jackrain.nea.core.query.QueryException;
import com.jackrain.nea.util.RedisOpsUtil;
import com.jackrain.nea.web.face.impl.UserImpl;
import com.jackrain.nea.web.security.SecurityWebUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * Created by nathan on 2016/7/26.
 */
@Component
public class MyAuthenticationListener implements AuthenticationListener {

    private static Logger logger= LoggerFactory.getLogger(MyAuthenticationListener.class.getName());

    //private SecurityWebUtils securityWebUtils;

    @Value("${raincloud.session.max-active}")
    private int maxSession;

    @Autowired
    private RedisOpsUtil<String,String> redisOpsUtil;

    @Autowired
    private CachingShiroSessionDao sessionDao;

    @Override
    public void onSuccess(AuthenticationToken token, AuthenticationInfo info) {
        UsernamePasswordToken authToken = (UsernamePasswordToken)token;
        UserImpl u = info.getPrincipals().oneByType(UserImpl.class);
        u.setLastloginip(authToken.getHost());
        Subject subject = SecurityUtils.getSubject();
        Session session = subject.getSession(true);
        try {
            SecurityWebUtils.setUserWithSuccess(u);
            session.setAttribute("user",token.getPrincipal());
        } catch (QueryException e) {
            e.printStackTrace();
        }

        String key = "user:"+u.getName();
        String cntKey = "usercnt:"+u.getName();
        int sessionNum = Integer.parseInt(redisOpsUtil.strRedisTemplate.opsForValue().get(cntKey).toString());
        if (sessionNum >= maxSession+1){
            String sessionId = redisOpsUtil.strRedisTemplate.opsForList().index(key,1);
            Session lastSession = (Session)redisOpsUtil.objRedisTemplate.opsForHash().get("session",sessionId);
            sessionDao.onDelete(lastSession);
            redisOpsUtil.strRedisTemplate.opsForSet().add("outsession",lastSession.getId().toString());
        }
    }

    @Override
    public void onFailure(AuthenticationToken token, AuthenticationException ae) {
        UsernamePasswordToken authToken = (UsernamePasswordToken)token;
        String username = authToken.getUsername();
        UserImpl user = new UserImpl();
        String IP = authToken.getHost();
        user.setName(username);
        user.setLastloginip(IP);
        try {
            SecurityWebUtils.setUserWithFailure(user);
        } catch (QueryException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onLogout(PrincipalCollection principals) {

    }
}
